using Godot;
using System.Collections.Generic;
using System.Linq;

public partial class TargetSearcher : Area2D
{
    // 攻击范围
    [Export] public float AttackRange = 200f;
    // 敌人物理层
    [Export(PropertyHint.Layers2DPhysics)] public uint EnemyLayer = 2;

    private readonly List<Node2D> _availableTargets = new List<Node2D>();
    private CollisionShape2D _detectionShape;

    public override void _Ready()
    {
        _detectionShape = GetNode<CollisionShape2D>("CollisionShape2D");
        this.AreaEntered += OnAreaEntered;
        this.AreaExited += OnAreaExited;
        UpdateDetectionRadius(AttackRange);
    }

    public void UpdateDetectionRadius(float radius)
    {
        var shape = new CircleShape2D();
        shape.Radius = radius;
        _detectionShape.Shape = shape;
    }

    private void OnAreaEntered(Node area)
    {
        if (area is Enemy enemy && !_availableTargets.Contains(enemy))
            _availableTargets.Add(enemy);
    }

    private void OnAreaExited(Node area)
    {
        if (area is Enemy enemy)
            _availableTargets.Remove(enemy);
    }

    /// <summary>
    /// 获取一个可用的攻击目标
    /// </summary>
    /// <returns></returns>
    public Node2D GetTarget()
    {
        return _availableTargets
            .Where(t => t.IsInsideTree() && !t.IsQueuedForDeletion())
            .OrderBy(t => t.GlobalPosition.DistanceTo(GlobalPosition))
            .FirstOrDefault();
    }
    /// <summary>
    /// 获取所有可用的攻击目标
    /// </summary>
    /// <returns></returns>
    public IEnumerable<Node2D> GetAllTargets()
    {
        return _availableTargets
            .Where(t => t.IsInsideTree() && !t.IsQueuedForDeletion());
    }
    
    public bool IsTargetInRange(Node2D target)
    {
        return _availableTargets.Contains(target);
    }
}